/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* http://www.gnu.org/copyleft/gpl.html
*/
package l1j.taki;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Random;

import l1j.server.L1DatabaseFactory;
import l1j.server.server.ActionCodes;
import l1j.server.server.GeneralThreadPool;
import l1j.server.server.IdFactory;
import l1j.server.server.datatables.NpcTable;
import l1j.server.server.model.L1Inventory;
import l1j.server.server.model.L1Teleport;
import l1j.server.server.model.L1World;
import l1j.server.server.model.Instance.L1ItemInstance;
import l1j.server.server.model.Instance.L1MonsterInstance;
import l1j.server.server.model.Instance.L1NpcInstance;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.serverpackets.S_BlueMessage;
import l1j.server.server.serverpackets.S_SystemMessage;
import l1j.server.server.utils.SQLUtil;

public class GameDG {

	public final ArrayList<L1PcInstance> _members = new ArrayList<L1PcInstance>();

	private static GameDG _instance;
	
	private Random _random = new Random();
	
	public static GameDG getInstance() {
		if (_instance == null) {
			_instance = new GameDG();
		}
		return _instance;
	}


	private int _cleartime = 60 * 1000;
	private int _speaktime = 10 * 1000;
	private int _bosstime = 1 * 1000;
	private int _lastboostime = 120 * 1000;
	private short _mapid = 91;

	private int _bossId1 = 45008; 
	private int _bossId2 = 45008; 
	private int _bossId3 = 45008; 
	private int _bossId4 = 45008; 
	private int _bossId5 = 45008; 
	private int _bossId6 = 45008; 
	private int _bossId7 = 45008; 
	private int _bossId8 = 45008; 
	private int _bossId9 = 45008; 
	private int _bossId10 = 45008; 

	public String enterDG(L1PcInstance pc, L1ItemInstance item) throws Exception {
		L1PcInstance leader = pc.getParty().getLeader();
		L1PcInstance member[] = pc.getParty().getMembers();
		short mapId = _mapid;
		int locx = 32702;
		int locy = 32893;
		mapId = (short) (_mapid + getMembersCount());

		if (getMembersCount() >= 6) {
			pc.sendPackets(new S_SystemMessage("副本已滿。"));
			return "";
		}
		for (int i = 0, a = member.length; i < a; i++) {
			if (member[i].getId() == leader.getId() || member[i] == null)
				continue;
			L1Teleport.teleport(leader, locx, locy, mapId, pc.getHeading(), true);
			pc.setDailyMapID(mapId);
			pc.save();
			addMembers(pc);
			pc.getInventory().removeItem(item, 1);
			switch (a){
			case 8:
				L1Teleport.teleport(member[7], locx, locy, mapId, pc.getHeading(), true);
				member[7].setDailyMapID(mapId);
				member[7].save();
			case 7:
				L1Teleport.teleport(member[6], locx, locy, mapId, pc.getHeading(), true);
				member[6].setDailyMapID(mapId);
				member[6].save();
			case 6:
				L1Teleport.teleport(member[5], locx, locy, mapId, pc.getHeading(), true);
				member[5].setDailyMapID(mapId);
				member[5].save();
			case 5:
				L1Teleport.teleport(member[4], locx, locy, mapId, pc.getHeading(), true);
				member[4].setDailyMapID(mapId);
				member[4].save();
			case 4:
				L1Teleport.teleport(member[3], locx, locy, mapId, pc.getHeading(), true);
				member[3].setDailyMapID(mapId);
				member[3].save();
			case 3:
				L1Teleport.teleport(member[2], locx, locy, mapId, pc.getHeading(), true);
				member[2].setDailyMapID(mapId);
				member[2].save();
			case 2:
				L1Teleport.teleport(member[1], locx, locy, mapId, pc.getHeading(), true);
				member[1].setDailyMapID(mapId);
				member[1].save();
				break;
			}
			return "";
		}
		return "";
	}
	
	private void addMembers(L1PcInstance pc) {
		_members.add(pc); 
		GeneralThreadPool.getInstance().execute(new runValokCave());
	}

	private class runValokCave implements Runnable {
		public void run() {
			short mapid = (short) (getMembersCount()+_mapid-1);
			try {
				sendMessage(mapid,"倒數10秒");
				Thread.sleep(5*1000);
				
				sendMessage(mapid,"5秒");
				Thread.sleep(1000);
				
				sendMessage(mapid,"4秒"); 
				Thread.sleep(1000);
					
				sendMessage(mapid,"3秒");
				Thread.sleep(1000);
					
				sendMessage(mapid,"2秒");
				Thread.sleep(1000);
					
				sendMessage(mapid,"1秒");
				Thread.sleep(1000);
				
				if (checkParty(mapid)){
					
					sendMessage(mapid,"炎魔：卑微的人類，想接近我？你還差太遠．．");
					Thread.sleep(_speaktime);
					
					spawnBoss(mapid,_bossId1,"1");
					Thread.sleep(_bosstime);
					
					spawnBoss(mapid,_bossId2,"2");
					Thread.sleep(_bosstime);
					
					spawnBoss(mapid,_bossId3,"3");
					Thread.sleep(_bosstime);
					
					spawnBoss(mapid,_bossId4,"4");
					Thread.sleep(_bosstime);
						
					spawnBoss(mapid,_bossId5,"5");
					Thread.sleep(_bosstime);
					
					sendMessage(mapid,"炎魔：哈哈．．已經抵擋不住了嗎");
					Thread.sleep(_speaktime);
					
					spawnBoss(mapid,_bossId6,"6");
					Thread.sleep(_bosstime);
					
					spawnBoss(mapid,_bossId7,"7");
					Thread.sleep(_bosstime);
					
					spawnBoss(mapid,_bossId8,"8");
					Thread.sleep(_bosstime);
					
					spawnBoss(mapid,_bossId9,"9");
					Thread.sleep(_bosstime);
					
					sendMessage(mapid,"炎魔：我要讓你嘗嘗真正的痛苦");
					Thread.sleep(_speaktime);
					
					spawnBoss(mapid,_bossId10,"10");
					Thread.sleep(_lastboostime);
					
					sendMessage(mapid,"炎魔：凡人．．我們終會有見面的一天");
					Thread.sleep(_speaktime);
					
					sendMessage(mapid,"倒數10秒副本結束");
					Thread.sleep(5*1000);
						
					sendMessage(mapid,"5秒");
					Thread.sleep(1000);
						
					sendMessage(mapid,"4秒");
					Thread.sleep(1000);
						
					sendMessage(mapid,"3秒");
					Thread.sleep(1000);
						
					sendMessage(mapid,"2秒");
					Thread.sleep(1000);
						
					sendMessage(mapid,"1秒");
					Thread.sleep(1000);
					
					endValokCave(mapid);
				}
				Thread.sleep(_cleartime);				
			}catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	private boolean checkParty(int mapid) {
		for (L1PcInstance pc : L1World.getInstance().getAllPlayers()) {
			if (!pc.isInParty()){
				if (pc.getMapId() == mapid && pc.getDailyMapID() == mapid){
					sendMessage(mapid,"檢察到玩家沒有組隊，副本強制結束");
					L1Teleport.teleport(pc, 33442, 32797, (short) 4, pc.getHeading(), true);
					endValokCave(mapid);
					return false;
				}
			}
		}
		return true;
	}
	
	private void endValokCave(int mapid) {
		switch (mapid){
		case 4946:
			clearMembers();
		default:
			sendMessage(mapid,"副本結束");
			for (L1PcInstance pc : L1World.getInstance().getAllPlayers()) {
				if (pc.getMapId() == mapid){
						L1Teleport.teleport(pc, 33442, 32797, (short) 4, pc.getHeading(), true);
					}
				}
			clearColosseum(mapid);
			break;
		}
	}	
	
	private void clearColosseum(int mapid) {
		for (Object obj : L1World.getInstance().getVisibleObjects(mapid).values()) {
			if (obj instanceof L1MonsterInstance) {
				L1MonsterInstance mob = (L1MonsterInstance) obj;
				if (!mob.isDead()) {
					mob.setDead(true);
					mob.setStatus(ActionCodes.ACTION_Die);
					mob.setCurrentHpDirect(0);
					mob.deleteMe();
				}
			} else if (obj instanceof L1Inventory) {
				L1Inventory inventory = (L1Inventory) obj;
				inventory.clearItems();
			}
		}
	}
	
	private void spawnBoss(int mapid, int npcid, String msg1) {
		if (msg1.equalsIgnoreCase("10")){
			sendMessage(mapid,"創造物["+ getBossName(npcid) +"]已加入戰場，10分鐘後副本結束");
			spawnlastboss(mapid,npcid);
		} else {
			sendMessage(mapid,"創造物["+ getBossName(npcid) +"]已加入戰場");
			spawn(mapid,npcid);
		}
	}
	private void spawnlastboss(int mapid, int npcid) {
		int _loc[][] = {{32841, 32752},{32841, 32758},{32841, 32764},{32841, 32770},
			{32836, 32752},{32836, 32758},{32836, 32764},{32836, 32770},
			{32830, 32752},{32830, 32758},{32830, 32764},{32830, 32770},
			{32823, 32752},{32823, 32758},{32823, 32764},{32823, 32770}};
		int rnd1 = _random.nextInt(16);
		try {
			L1NpcInstance npc = NpcTable.getInstance().newNpcInstance(npcid);
			npc.setId(IdFactory.getInstance().nextId());
			npc.setMap((short) mapid);
			npc.setX(_loc[rnd1][0]);
			npc.setY(_loc[rnd1][1]);
			Thread.sleep(1);
			npc.setHomeX(npc.getX());
			npc.setHomeY(npc.getY());
			npc.setHeading(4);
	
			L1World.getInstance().storeObject(npc);
			L1World.getInstance().addVisibleObject(npc);
			npc.turnOnOffLight();
			npc.startChat(L1NpcInstance.CHAT_TIMING_APPEARANCE);
	
		} catch (Exception e) {
		}
	}
	
	private void spawn(int mapid, int npcid) {
		int _loc[][] = {{32702, 32878},{32686, 32894},{32700, 32910},{32716, 32894}};
		L1NpcInstance npc;
		for (int i = 0 ; i < 4 ; i++){
			try {
				npc = new L1NpcInstance(null);
				npc = NpcTable.getInstance().newNpcInstance(npcid);
				npc.setId(IdFactory.getInstance().nextId());
				npc.setMap((short) mapid);
				npc.setX(_loc[i][0]);
				npc.setY(_loc[i][1]);
				Thread.sleep(1);
				npc.setHomeX(npc.getX());
				npc.setHomeY(npc.getY());
				npc.setHeading(4);
				
				L1World.getInstance().storeObject(npc);
				L1World.getInstance().addVisibleObject(npc);
				npc.turnOnOffLight();
				npc.startChat(L1NpcInstance.CHAT_TIMING_APPEARANCE);
				
			} catch (Exception e) {
			}
		}
	}
	
	private String getBossName(int npcId) {
		String BossName = null;
		Connection con = null;
		PreparedStatement pstm = null;
		ResultSet rs = null;
		try {
			con = L1DatabaseFactory.getInstance().getConnection();
			pstm = con.prepareStatement("select name from npc where npcid = ?");
			pstm.setInt(1, npcId);
			rs = pstm.executeQuery();
			if (rs.next()) {
				BossName = rs.getString("name");
			}
		} catch (SQLException e) {
		} finally {
			SQLUtil.close(rs);
			SQLUtil.close(pstm);
			SQLUtil.close(con);
		}
		return BossName;
	}
	
	private void sendMessage(int mapid, String msg) {
		for (L1PcInstance pc : L1World.getInstance().getAllPlayers()) {
			if (pc.getMapId() == mapid){
				pc.sendPackets(new S_BlueMessage(166,"\\f3" + msg));
			}
		}
	}
	
	private void clearMembers() {
		_members.clear();
	}
	
	public int getMembersCount() {
		return _members.size();
	}	
}